﻿using System;
using System.Security.Cryptography;
using System.Text;

namespace yc.Site
{
	#region MD5加密算法
	/// <summary>
	/// MD5加密算法
	/// </summary>
	public static class MD5
	{
		/// <summary>
		/// Create a salt 
		/// </summary>
		/// <param name="size">A salt size</param>
		/// <returns>A salt</returns>
		public static string NewSalt(int size = 8)
		{
			var provider = new RNGCryptoServiceProvider();
			byte[] data = new byte[size];
			provider.GetBytes(data);
			return Convert.ToBase64String(data);
		}

		/// <summary>
		/// MD5加密算法
		/// </summary>
		/// <param name="strSource">待加密字串</param>
		/// <returns>加密后的字串</returns>
		public static string Encrypt(string strSource)
		{
			return Encrypt(strSource, 32);
		}

		/// <summary>
		/// MD5加密算法
		/// </summary>
		/// <param name="strSource">待加密字串</param>
		/// <param name="length">16或32值之一,其它则采用.net默认MD5加密算法</param>
		/// <returns>加密后的字串</returns>
		public static string Encrypt(string strSource, int length = 32)
		{
			return Encrypt(strSource, Encoding.ASCII.EncodingName, length);
		}

		/// <summary>
		/// MD5加密算法
		/// </summary>
		/// <param name="strSource">待加密字串</param>
		/// <param name="strCoding">加密字符串编码</param>
		/// <param name="length">16或32值之一,其它则采用.net默认MD5加密算法</param>
		/// <returns></returns>
		public static string Encrypt(string strSource, string strCoding, int length = 32)
		{
			byte[] bytes = Encoding.GetEncoding(strCoding).GetBytes(strSource);
			byte[] hashValue = ((HashAlgorithm)CryptoConfig.CreateFromName("MD5")).ComputeHash(bytes);
			StringBuilder sb = new StringBuilder();
			length = length > 32 ? 32 : length;
			for (int i = 8 - length / 4; i < 8 + length / 4; i++) sb.Append(hashValue[i].ToString("x2"));
			//convertor(sb);
			return sb.ToString();
		}

		/// <summary>
		/// MD5加密扩展
		/// </summary>
		/// <param name="sb"></param>
		private static void convertor(StringBuilder sb)
		{
			int step = sb.Length / 2;
			for (int i = sb.Length / 2 - 1; i >= 0; i -= 2)
			{
				if (i % 2 > 0)
				{
					char c = (char)((sb[i] > '9' ? 'a' + 'f' : '0' + '9') - sb[i]);
					sb[i] = (char)((sb[i + step] > '9' ? 'a' + 'f' : '0' + '9') - sb[i + step]);
					sb[i + step] = c;
				}
			}
		}
	}
	#endregion
}
